package com.voltmao.webpro.utils.wechat.utils;

import com.voltmao.webpro.utils.StringUtils;
import com.voltmao.webpro.utils.http.HttpsClientUtils;
import com.voltmao.webpro.utils.http.PostReportData;
import com.voltmao.webpro.utils.wechat.IWechatUtils;
import com.voltmao.webpro.utils.wechat.core.Account;
import com.voltmao.webpro.utils.wechat.utils.dto.pay.PayMsg;
import com.voltmao.webpro.utils.wechat.utils.dto.pay.RedPackMsg;
import org.apache.http.conn.ssl.SSLContexts;

import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * 支付工具类
 */
public class PayUtils {

    private Map<String, String> wxConfig;
    private Account account;
    private SSLContext sslContext;                                                      //该商家的私钥证书

    private static Logger logger = Logger.getLogger(PayUtils.class.getName());


    public PayUtils(IWechatUtils wechatUtils) {
        this.account = wechatUtils.getAccount();
        this.wxConfig = wechatUtils.getWxConfig();

        //证书信息
        if (!StringUtils.isEmpty(this.account.getCertFileUrl())) {
            try {
                String path = this.getClass().getClassLoader().getResource("").getPath() + "/" + this.account.getCertFileUrl();
//                logger.info("加载公钥证书地址:"+path);
                this.sslContext = builderSSLContext(this.account.getMerId(), path);
            } catch (Exception e) {
                logger.info("加载公钥证书失败");
                e.printStackTrace();
            }
        }
    }

    /**
     * 发起红包
     *
     * @param redPackMsg
     * @return
     * @demo redPackMsg.setAct_name("现金提现");
     * redPackMsg.setRemark(String.format("本次提现金额:%.2f元,请注意查收!",price));
     * redPackMsg.setWishing("余额提现!");
     * redPackMsg.setTotal_num("1");
     * redPackMsg.setClient_ip(ip);
     * redPackMsg.setTotal_amount((int)(price*100)+"");
     * redPackMsg.setRe_openid(openId);
     */
    public String sendRedPack(RedPackMsg redPackMsg) {

        String result;
        //加载微信账户信息
        redPackMsg.initAccount(this.account);
        try {
            String sendUrl = wxConfig.get("wx.pay.redPark");

            logger.info("pay==>:\n" + redPackMsg.toXml());
            //构造报文数据并进行提交
            PostReportData reportData = new PostReportData();
            reportData.setOutStr(redPackMsg.toXml());
            result = HttpsClientUtils.sendSSLPost(sendUrl, sslContext, reportData, new HttpsClientUtils.HttpsClientCall() {
                @Override
                public void success(String data) {
                    //TODO 调用成功后的处理方法
                    logger.info("pay<==:/n" + data);
                }
            });

        } catch (Exception e) {
            result = e.toString();
            e.printStackTrace();
        }

        return result;
    }


    /**
     * 企业付款到到用户
     *
     * @return
     */
    public String sendPayToUser() {

        return "";
    }

    /**
     * 发起支付请求[预支付]
     * <p>
     * 需要公从号=> 微信支付=> 开发配置=> 授权支付目录
     *
     * @param backCellUrl 回调地址路径
     * @param openId      openid
     * @param money       金额(元)
     * @param ip          IP地址
     * @param payDes      支付描述
     * @return
     */
    public String sendPayRequest(String backCellUrl, String openId, String payDes, String ip, double money) {
        //构造回传信息
        Map<String, Object> params = new HashMap<>();
        params.put("openId", openId);
        params.put("createTM", System.currentTimeMillis() + "");
        params.put("payDes", StringUtils.getUrlEncode(payDes, "UTF-8"));

        PayMsg payMsg = new PayMsg(payDes, openId, (int) (money * 100), ip, backCellUrl, params);
        payMsg.initAccount(this.account);

        String result;
        try {
            String sendUrl = wxConfig.get("wx.pay.unifiedorder");
            logger.info("pay send==>:\n" + payMsg.toXml());

            //构造报文数据并进行提交
            PostReportData reportData = new PostReportData();
            reportData.setOutStr(payMsg.toXml());
            result = HttpsClientUtils.sendSSLPost(sendUrl, sslContext, reportData, null);

        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }

        logger.info("<==pay send:\n" + result);

        //二次加密 + 构造返回内容
        return payMsg.builderResult(result);
    }

    /**
     * 构造私钥上下文
     *
     * @param merId   商户号
     * @param fileUrl 文件路径
     * @return
     * @throws Exception
     */
    private SSLContext builderSSLContext(String merId, String fileUrl) throws Exception {

        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        FileInputStream instream = new FileInputStream(new File(fileUrl));
        try {
            //设置证书密码
            keyStore.load(instream, merId.toCharArray());
        } finally {
            instream.close();
        }

        // Trust own CA and all self-signed certs
        SSLContext sslcontext = SSLContexts.custom()
                .loadKeyMaterial(keyStore, merId.toCharArray())
                .build();

        return sslcontext;
    }

}
